package com.nlscan.qdkit.ui.publico.config;

import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextUtils;
import android.widget.EditText;

import com.nlscan.qdkit.ui.publico.R;
import com.nlscan.qdkit.ui.publico.component.MyCheckEditView;
import com.quvii.qvlib.util.QvRegexUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class InputCheckHelper {
    //检查账号输入的合法性, 返回具体值,表示不通过(包含原因), 返回null, 表示检测通过
//    public static boolean checkAccountFormat(MyCheckEditView editView, String account) {
//        if (TextUtils.isEmpty(account)) {
//            editView.showInfo(R.string.key_username_empty_hint);
//            return false;
//        }
//
//        //判断是不是纯数字
//        if (QvTextUtil.checkNumber(account)) {
//            //纯数字, 按手机号码提示
//            editView.showInfo(R.string.key_add_friend_add_phone_number_friend_hint);
//            return false;
//        }
//
//        //检测通过
//        return true;
//    }


    public static boolean checkEmailFormat(MyCheckEditView editView, String email) {
        if (TextUtils.isEmpty(email)) {
            editView.showInfo(R.string.input_email);
            return false;
        }

        //是否为邮箱
        /*if (!email.contains("@")) {
            editView.showInfo(R.string.email_error);
            return false;
        }*/

        //检测通过
        return true;
    }

//
//    //检查账号输入的合法性, 返回具体值,表示不通过(包含原因), 返回null, 表示检测通过
//    public static boolean checkAccountPasswordFormat(MyCheckEditView editView, String password) {
//        if (TextUtils.isEmpty(password)) {
//            editView.showInfo(R.string.key_username_empty_hint);
//            return false;
//        }
//
//        //检测通过
//        return true;
//    }

    public static boolean checkIpOrDomainFormat(String input) {
        return QvRegexUtils.isIP(input) || QvRegexUtils.isDomainName(input);
    }

    public static void setNotEmptyCheck(MyCheckEditView myCheckEditView, int hint) {
        setNotEmptyCheck(myCheckEditView, myCheckEditView.getContext().getString(hint), null);
    }

    public static void setNotEmptyCheck(MyCheckEditView myCheckEditView, String hint) {
        setNotEmptyCheck(myCheckEditView, hint, null);
    }

    public static void setNotEmptyCheck(MyCheckEditView myCheckEditView, OnCheckListener listener) {
        setNotEmptyCheck(myCheckEditView, myCheckEditView.getContext().getString(R.string.general_input_empty), listener);
    }

    public static void setNotEmptyCheck(MyCheckEditView myCheckEditView, int hint, OnCheckListener listener) {
        setNotEmptyCheck(myCheckEditView, myCheckEditView.getContext().getString(hint), listener);
    }

    public static void setNotEmptyCheck(MyCheckEditView myCheckEditView, String hint, OnCheckListener listener) {
        myCheckEditView.setOnInputChangeListener(s -> {
            if (TextUtils.isEmpty(s)) {
                myCheckEditView.showInfo(hint);
                if (listener != null) {
                    listener.onCheck(false);
                }
            } else {
                myCheckEditView.showInfo("");
                if (listener != null) {
                    listener.onCheck(true);
                }
            }
        });
    }

    public static void setEmailCheck(MyCheckEditView myCheckEditView, OnCheckListener listener) {
        myCheckEditView.setOnInputChangeListener(s -> {
            if (TextUtils.isEmpty(s)) {
                myCheckEditView.showInfo("");
                listener.onCheck(false);
            } else if (!s.contains("@")) {
                myCheckEditView.showInfo(myCheckEditView.getContext().getString(R.string.email_error));
                listener.onCheck(false);
            } else {
                myCheckEditView.showInfo("");
                listener.onCheck(true);
            }
        });
    }

    //    public static void setPhoneCheck(MyCheckEditView myCheckEditView, OnCheckListener listener) {
//        myCheckEditView.setOnInputChangeListener(s -> {
//            if (TextUtils.isEmpty(s)) {
//                myCheckEditView.showInfo("");
//                listener.onCheck(false);
//            } else if (!s.startsWith("+")) {
//                myCheckEditView.showInfo(myCheckEditView.getContext().getString(R.string.key_add_friend_add_phone_number_friend_hint));
//                listener.onCheck(false);
//            } else {
//                myCheckEditView.showInfo("");
//                listener.onCheck(true);
//            }
//        });
//    }
//
//    public static void setAccountPasswordCheck(MyCheckEditView passwordView, MyCheckEditView confirmPasswordView, OnCheckListener listener) {
//        passwordView.setOnInputChangeListener(s -> {
//            if (TextUtils.isEmpty(s)) {
//                passwordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            if (s.length() < PublicoConfig.ACCOUNT_PASSWORD_MIN_LENGTH || s.length() > PublicoConfig.ACCOUNT_PASSWORD_MAX_LENGTH) {
//                passwordView.showInfo(passwordView.getContext().getString(R.string.key_password_6_16_character));
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!QvTextUtil.checkPassword(s, PublicoConfig.ACCOUNT_PASSWORD_MIN_LENGTH, PublicoConfig.ACCOUNT_PASSWORD_MAX_LENGTH)) {
//                passwordView.showInfo(passwordView.getContext().getString(R.string.key_password_format_error));
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!TextUtils.isEmpty(confirmPasswordView.getInputText()) && !s.equals(confirmPasswordView.getInputText())) {
//                passwordView.showInfo("");
//                confirmPasswordView.showInfo(passwordView.getContext().getString(R.string.key_password_mismatch));
//                listener.onCheck(false);
//                return;
//            }
//
//            passwordView.showInfo("");
//            confirmPasswordView.showInfo("");
//            listener.onCheck(true);
//        });
//
//        confirmPasswordView.setOnInputChangeListener(s -> {
//            if (TextUtils.isEmpty(s)) {
//                confirmPasswordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!s.equals(passwordView.getInputText())) {
//                confirmPasswordView.showInfo(confirmPasswordView.getContext().getString(R.string.key_password_mismatch));
//                listener.onCheck(false);
//                return;
//            }
//
//            confirmPasswordView.showInfo("");
//            listener.onCheck(true);
//        });
//    }
    
//    public static void setDeviceVerificationCodeCheck(Device device, MyCheckEditView passwordView, MyCheckEditView confirmPasswordView, OnCheckListener listener) {
//        boolean isOnlyNum = device.getDeviceModel() == Device.DEVICE_MODEL_VDP;
//
//        if (isOnlyNum) {
//            passwordView.getEtInput().setInputType(InputType.TYPE_CLASS_NUMBER);
//            confirmPasswordView.getEtInput().setInputType(InputType.TYPE_CLASS_NUMBER);
//        }
//
//        MyCheckEditView.OnInputChangeListener onInputListener = s -> {
//            if (TextUtils.isEmpty(s)) {
//                passwordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            if (s.length() < PublicoConfig.PASSWORD_MIN_LENGTH || s.length() > PublicoConfig.PASSWORD_MAX_LENGTH) {
//                passwordView.showInfo(passwordView.getContext().getString(R.string.key_check_code_len_tip));
//                listener.onCheck(false);
//                return;
//            }
//
//            if (device.getDeviceModel() == Device.DEVICE_MODEL_VDP && !device.getDeviceAbility().isSupportNoLoginShare()) {
//                //只有不支持免密开锁的VDP设备, 修改密码才只能输入数字
//                if (!QvTextUtil.checkNumber(s)) {
//                    passwordView.showInfo(passwordView.getContext().getString(R.string.key_pwd_format_error_numbers));
//                    listener.onCheck(false);
//                    return;
//                }
//            } else {
//                if (!QvTextUtil.checkLetterAndNum(s)) {
//                    passwordView.showInfo(passwordView.getContext().getString(R.string.key_check_code_error));
//                    listener.onCheck(false);
//                    return;
//                }
//            }
//
//            if (!TextUtils.isEmpty(confirmPasswordView.getInputText()) && !s.equals(confirmPasswordView.getInputText())) {
//                passwordView.showInfo("");
//                confirmPasswordView.showInfo(passwordView.getContext().getString(R.string.key_check_code_not_match));
//                listener.onCheck(false);
//                return;
//            }
//
//            if (TextUtils.isEmpty(confirmPasswordView.getInputText())) {
//                passwordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            passwordView.showInfo("");
//            confirmPasswordView.showInfo("");
//            listener.onCheck(true);
//        };
//
//        passwordView.setOnInputChangeListener(onInputListener);
//
//        confirmPasswordView.setOnInputChangeListener(s -> {
//            if (TextUtils.isEmpty(s)) {
//                confirmPasswordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!s.equals(passwordView.getInputText())) {
//                confirmPasswordView.showInfo(confirmPasswordView.getContext().getString(R.string.key_check_code_not_match));
//                listener.onCheck(false);
//                return;
//            }
//
//            confirmPasswordView.showInfo("");
//            onInputListener.onChange(passwordView.getInputText());
//        });
//    }
//
//    public static void setDeviceUnlockPasswordCheck(Device device, MyCheckEditView passwordView, MyCheckEditView confirmPasswordView, OnCheckListener listener) {
//        // TODO: 2020/4/24 设置输入格式
//
//        passwordView.setOnInputChangeListener(s -> {
//            if (TextUtils.isEmpty(s)) {
//                passwordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            if (s.length() < AppConst.PASSWORD_MIN_LENGTH || s.length() > PublicoConfig.PASSWORD_MAX_LENGTH) {
//                passwordView.showInfo(passwordView.getContext().getString(R.string.key_device_manager_pwd_len_tip));
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!QvTextUtil.checkNumber(s)) {
//                passwordView.showInfo(passwordView.getContext().getString(R.string.key_pwd_format_error_numbers));
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!TextUtils.isEmpty(confirmPasswordView.getInputText()) && !s.equals(confirmPasswordView.getInputText())) {
//                passwordView.showInfo("");
//                confirmPasswordView.showInfo(passwordView.getContext().getString(R.string.key_password_mismatch));
//                listener.onCheck(false);
//                return;
//            }
//
//            passwordView.showInfo("");
//            confirmPasswordView.showInfo("");
//            listener.onCheck(true);
//        });
//
//        confirmPasswordView.setOnInputChangeListener(s -> {
//            if (TextUtils.isEmpty(s)) {
//                confirmPasswordView.showInfo("");
//                listener.onCheck(false);
//                return;
//            }
//
//            if (!s.equals(passwordView.getInputText())) {
//                confirmPasswordView.showInfo(confirmPasswordView.getContext().getString(R.string.key_password_mismatch));
//                listener.onCheck(false);
//                return;
//            }
//
//            confirmPasswordView.showInfo("");
//            listener.onCheck(true);
//        });
//    }

    public static void setAccountInputFilter(EditText view) {
        //过滤<>和空格
        setEditTextInputFilter(view,
                PublicoConfig.APP_ACCOUNT_FILTER_REGEX, PublicoConfig.DEFAULT_INPUT_MAX_BYTES);
    }

    public static void setAccountInputFilter(MyCheckEditView view) {
        setAccountInputFilter(view.getEtInput());
    }

    public static void setRegisterPasswordInputFilter(EditText view) {
        setEditTextDefaultInputFilter(view, PublicoConfig.APP_REGISTER_PASSWORD_MAX_LENGTH);
    }

    public static void setLoginPasswordInputFilter(EditText view) {
        setDefaultInputFilter(view);
    }

    public static void setNickNameInputFilter(EditText view) {
        setDefaultInputFilter(view);
    }

    public static void setNewPwdProtectInputFilter(EditText view) {
        setEditTextDefaultInputFilter(view, PublicoConfig.APP_NEW_PASSWORD_PROTECT_MAX_LENGTH);
    }

    public static void setDeviceNameInputFilter(EditText view) {
        setDefaultInputFilter(view);
    }

    // 设置Qv设备校验码(密码)
    public static void setQvDeviceAuthCodeInputFilter(EditText view) {
        setEditTextInputFilter(view, PublicoConfig.DEFAULT_INPUT_FILTER_REGEX, PublicoConfig.PASSWORD_MAX_LENGTH);
    }

    public static void setHsDeviceUsernameInputFilter(EditText view) {
        setDefaultInputFilter(view);
    }

    public static void setHsDevicePasswordInputFilter(EditText view) {
        setDefaultInputFilter(view);
    }

    public static void setDeviceUidInputFilter(EditText view) {
        setEditTextInputFilter(view,
                PublicoConfig.DEVICE_UID_FILTER_REGEX, PublicoConfig.DEFAULT_INPUT_MAX_BYTES);
    }

    public static void setDebugPageInputFilter(EditText view) {
        setEditTextInputFilter(view,
                PublicoConfig.DEFAULT_INPUT_FILTER_REGEX, -1);
    }

    public static void setDefaultInputFilter(EditText view) {
        setEditTextInputFilter(view,
                PublicoConfig.DEFAULT_INPUT_FILTER_REGEX, PublicoConfig.DEFAULT_INPUT_MAX_BYTES);
    }

    private static void setEditTextInputSpace(EditText editText, String format) {
        InputFilter filter = (source, start, end, dest, dstart, dend) -> {
            Pattern pattern = Pattern.compile(format);
            Matcher matcher = pattern.matcher(source.toString());
            return matcher.find() ? "" : null;
        };
        editText.setFilters(new InputFilter[]{filter});
    }

    /**
     * 设置editText 要过滤的字符
     *
     * @param editText
     * @param filterRegex 过滤规则
     * @param maxBytes
     */
    public static void setEditTextInputFilter(EditText editText, final String filterRegex, int maxBytes) {
        if (editText == null) {
            return;
        }

        InputFilter inputFilter = (source, start, end, dest, dstart, dend) -> {
            if (source == null) return null;
            Pattern pattern = Pattern.compile(filterRegex);
            Matcher matcher = pattern.matcher(source.toString());
            if (!matcher.find()) {
                return null;
            }
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < source.length(); i++) {
                char asciiChar = source.charAt(i);
                boolean isFilter = pattern.matcher(asciiChar + "").find();
                if (!isFilter) {
                    stringBuilder.append(asciiChar);
                }
            }
            return stringBuilder;
        };
        InputFilter bytesFilter = new BytesFilter(maxBytes);

        boolean supportRegexFilter = !TextUtils.isEmpty(filterRegex);
        boolean supportBytesFilter = maxBytes > 0;
        InputFilter[] filters = null;
        if (supportRegexFilter && supportBytesFilter) {
            filters = new InputFilter[]{inputFilter, bytesFilter};
        } else if (supportRegexFilter) {
            filters = new InputFilter[]{inputFilter};
        } else if (supportBytesFilter) {
            filters = new InputFilter[]{bytesFilter};
        }
        if (filters != null) {
            editText.setFilters(filters);
        }
    }

    public static void setEditTextDefaultInputFilter(EditText view, int maxLength) {
        setEditTextDefaultInputFilter(view, true, maxLength);
    }

    /**
     * 过滤EditText输入内容，并对长度做限制
     * 只允许输入
     * 1. 数字
     * 2. 大小写字母英文
     * 3. 特殊字符（不允许输入 < >）
     * 新增：
     * 162: ¢
     * 163: £
     * 165:  ¥
     * 183:  ·
     * 8364: € （欧元）
     * 8369: ₱  (希腊)
     *
     * @param view        要注入过滤条件的View
     * @param filterValue 是否要过滤特殊字符
     * @param maxLength   最大字符长度
     */
    public static void setEditTextDefaultInputFilter(EditText view, boolean filterValue, int maxLength) {

        InputFilter inputFilter = (source, start, end, dest, dstart, dend) -> {
            if (source == null) return null;

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < source.length(); i++) {
                char asciiChar = source.charAt(i);
                if ((asciiChar >= 32 && asciiChar <= 59)
                        || asciiChar == 61
                        || (asciiChar >= 63 && asciiChar <= 126)
                        || asciiChar == 162
                        || asciiChar == 163
                        || asciiChar == 165
                        || asciiChar == 8364
                        || asciiChar == 8369) {
                    stringBuilder.append(asciiChar);
                }
            }
            return stringBuilder;
        };

        InputFilter lengthFilter = new InputFilter.LengthFilter(maxLength);
//        InputFilter bytesFilter = new BytesFilter(maxLength);

        boolean supportLengthFilter = maxLength > 0;
        InputFilter[] filters;
        if (filterValue) {
            if (supportLengthFilter) {
                filters = new InputFilter[]{inputFilter, lengthFilter};
            } else {
                filters = new InputFilter[]{inputFilter};
            }
        } else {
            if (supportLengthFilter) {
                filters = new InputFilter[]{lengthFilter};
            } else {
                //两个都不过滤, 直接结束
                return;
            }
        }

        view.setFilters(filters);
    }

    /**
     * 最大字节数限制过滤器
     */
    public static class BytesFilter implements InputFilter {

        private final int mMax;

        public BytesFilter(int max) {
            mMax = max;
        }

        /**
         * @param source 输入的文字
         * @param start  输入-0，删除-0
         * @param end    输入-文字的长度，删除-0
         * @param dest   原先显示的内容
         * @param dstart 输入-原光标位置，删除-光标删除结束位置
         * @param dend   输入-原光标位置，删除-光标删除开始位置
         * @return
         */
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            int destByteLength = dest.toString().getBytes().length;
            // [bugFix]修复过滤异常问题
            //[定位] 输入法英文预测导致（下划线）
            int realAddByteLength = 0;
            if (!TextUtils.isEmpty(source)) { //source为空表示删除操作
                // 表示输入字符
                String sourceStr = source.toString();
                int beginIndex = dend - dstart;
                if (beginIndex >= 0 && beginIndex < sourceStr.length()) {
                    realAddByteLength = sourceStr.substring(beginIndex).getBytes().length;
                }
            }
            int keep = mMax - destByteLength;  // 剩余可输入字节数
            if (keep <= 0) {
                if (dend - dstart > 0 && !TextUtils.isEmpty(source)) {
                    // 删除时会出现越界
                    int endIndex = Math.min(dend - dstart, source.length());
                    return source.subSequence(0, endIndex);
                } else {
                    return "";
                }
            } else if (keep >= realAddByteLength) {
                return null; // keep original
            } else {
                int cut = 0;    // 截取的字符长度
                int countBytes = 0; // 累计的可输入字节长度
                for (int i = 0; i < source.length(); i++) {
                    int byteLength = source.subSequence(i, i + 1).toString().getBytes().length;
                    countBytes += byteLength;
                    if (countBytes <= keep) {
                        cut++;
                    } else {
                        break;
                    }
                }
                if (cut <= 0) {
                    return "";
                } else {
                    return source.subSequence(start, cut);
                }
            }
        }
    }


    public interface OnCheckListener {
        void onCheck(boolean isPass);
    }
}
